package com.cloudbroker.bcs.platform.ltb.middle.bizservice.impl;

import com.alibaba.fastjson.JSON;
import com.cloudbroker.bcs.common.util.VOUtil;
import com.cloudbroker.bcs.platform.ltb.bizapi.constants.HSBCPSErrorCodes;
import com.cloudbroker.bcs.platform.ltb.bizapi.constants.status.*;
import com.cloudbroker.bcs.platform.ltb.bizapi.constants.type.CommentType;
import com.cloudbroker.bcs.platform.ltb.bizapi.constants.type.UpvoteType;
import com.cloudbroker.bcs.platform.ltb.bizapi.constants.type.UserType;
import com.cloudbroker.bcs.platform.ltb.bizapi.service.admin.back.CommentQueryResult;
import com.cloudbroker.bcs.platform.ltb.bizapi.service.admin.back.CommentVO;
import com.cloudbroker.bcs.platform.ltb.bizapi.service.admin.back.UserEntityVO;
import com.cloudbroker.bcs.platform.ltb.bizapi.service.comment.CommentBizService;
import com.cloudbroker.bcs.platform.ltb.bizapi.service.comment.back.CommentSaveBack;
import com.cloudbroker.bcs.platform.ltb.bizapi.service.comment.back.CommentSearchResult;
import com.cloudbroker.bcs.platform.ltb.bizapi.service.comment.back.CommentSearchResultData;
import com.cloudbroker.bcs.platform.ltb.bizapi.service.comment.back.CommentUpvoteResult;
import com.cloudbroker.bcs.platform.ltb.bizapi.service.comment.vo.*;
import com.cloudbroker.bcs.platform.ltb.bizapi.service.user.back.UsersQueryVo;
import com.cloudbroker.bcs.platform.ltb.middle.entity.*;
import com.cloudbroker.bcs.platform.ltb.middle.extservice.usercenter.UserCenterService;
import com.cloudbroker.bcs.platform.ltb.middle.service.BlackuserService;
import com.cloudbroker.bcs.platform.ltb.middle.service.CombineService;
import com.cloudbroker.bcs.platform.ltb.middle.service.CommentService;
import com.cloudbroker.bcs.platform.ltb.middle.service.UpvoteRecordService;
import com.cloudbroker.bcs.platform.ltb.middle.util.StringReplacer;
import com.cloudbroker.bcs.platform.ltb.middle.util.StringUtil;
import com.cloudbroker.bcs.platform.ltb.middle.util.UpvoteCacheUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.cloudbroker.bcs.platform.ltb.bizapi.constants.HSBCPSErrorCodes.ClientErr.COMMENT_BLACK_WORD_EXIT;
import static com.cloudbroker.bcs.platform.ltb.bizapi.constants.HSBCPSErrorCodes.ClientErr.USER_IN_BLACK_LIST;

/**
 * Created by zhaosh19213 on 2016/7/15.
 */
@Service
public class CommentBizServiceImpl implements CommentBizService {

    @Resource
    private CommentService commentService;

    @Resource
    private BlackuserService blackuserService;

    @Resource
    private CombineService combineService;

    @Resource
    private UpvoteRecordService upvoteRecordService;

    @Resource
    private UserCenterService userCenterService;

    public CommentSaveBack funcSaveComment(CommentAddForm commentAddForm){
        String comment_content = commentAddForm.getComment_content();
        if(StringReplacer.hasSensitiveWord(comment_content,commentAddForm.getCompany_id())){
            return VOUtil.genErrorResult(COMMENT_BLACK_WORD_EXIT,CommentSaveBack.class);
        }
        Long user_id = commentAddForm.getUser().getUser_id();
        if(blackuserService.isUserExit(new BlackUser(null,user_id,""))){
            return VOUtil.genErrorResult(USER_IN_BLACK_LIST,CommentSaveBack.class);
        }
        String comment_type = commentAddForm.getComment_type();
        //判断评论类别
        if (comment_type.equals(CommentType.COMBINATION.getVal())){
            //组合评论需要用combi_code装换成comment_id
            CombinationEntity combinationEntity =
                    combineService.getCombinationByCode(commentAddForm.getComment_target_id());
            if (combinationEntity == null) {
                return VOUtil.genErrorResult(HSBCPSErrorCodes.CombinationErrorInfo.COMBINATION_NOT_EXIST,
                        CommentSaveBack.class);
            }
            commentAddForm.setComment_target_id(String.valueOf(combinationEntity.getCombination_id()));
        }else {
            return VOUtil.genErrorResult(HSBCPSErrorCodes.CommentErrorInfo.NOT_AVAILIABLE_TYPE,
                    CommentSaveBack.class);
        }
        long comment_target_id  = Long.valueOf(commentAddForm.getComment_target_id());
        String company_id = commentAddForm.getUser().getCompany_id();
        CommentMsg commentMsg = new CommentMsg();
        commentMsg.setComment_content(comment_content);
        commentMsg.setComment_target_id(comment_target_id);
        commentMsg.setComment_type(comment_type);
        commentMsg.setCompany_id(company_id);
        commentMsg.setCreate_time(System.currentTimeMillis());
        commentMsg.setUpdate_time(System.currentTimeMillis());
        commentMsg.setIs_top(TopStatus.NOT_TOP.getVal());
        commentMsg.setClose_status(String.valueOf(CloseStatus.NORMAL.getVal()));
        commentMsg.setComment_status(String.valueOf(CommentStatus.DEFAULT.getVal()));
        commentMsg.setUser_id(user_id);
        commentMsg.setUpvote_num(0);
        commentService.save(commentMsg);
        CommentSaveBack commentSaveBack = new CommentSaveBack();
        return VOUtil.setSuccessResult(commentSaveBack);
    }

    @Transactional
    public CommentSaveBack funcSaveCommentReply(CommentReplyForm commentReplyForm) {
        Long reply_comment_id = Long.valueOf(commentReplyForm.getReply_comment_id());
        String comment_content = commentReplyForm.getComment_content();
        if(StringReplacer.hasSensitiveWord(comment_content,commentReplyForm.getCompany_id())){
            return VOUtil.genErrorResult(COMMENT_BLACK_WORD_EXIT,CommentSaveBack.class);
        }
        Long user_id = commentReplyForm.getUser().getUser_id();
        if(blackuserService.isUserExit(new BlackUser(null,user_id,""))){
            return VOUtil.genErrorResult(USER_IN_BLACK_LIST,CommentSaveBack.class);
        }
        String company_id = commentReplyForm.getUser().getCompany_id();

        CommentMsg commentMsg = new CommentMsg();
        commentMsg.setReply_comment_id(reply_comment_id);
        CommentMsg reply_comment = commentService.get(String.valueOf(reply_comment_id));
        if (reply_comment == null ){
            return VOUtil.genErrorResult(HSBCPSErrorCodes.CommentErrorInfo.COMMENT_NOT_EXIST,CommentSaveBack.class);
        }else if (reply_comment.getReply_comment_id() != null){
            return VOUtil.genErrorResult(HSBCPSErrorCodes.CommentErrorInfo.REPLY_CAN_NOT_REPLY,CommentSaveBack.class);
        }
        //是否回复过
        int count = commentService.count(commentMsg);
        if (count > 0){
            return VOUtil.genErrorResult(HSBCPSErrorCodes.CommentErrorInfo.COMMENT_ALREADY_REPLY,CommentSaveBack.class);
        }
        //回复的保存
        commentMsg.setComment_type(reply_comment.getComment_type());
        commentMsg.setComment_content(comment_content);
        commentMsg.setCompany_id(company_id);
        commentMsg.setCreate_time(System.currentTimeMillis());
        commentMsg.setUpdate_time(System.currentTimeMillis());
        commentMsg.setIs_top(TopStatus.NOT_TOP.getVal());
        commentMsg.setClose_status(String.valueOf(CloseStatus.NORMAL.getVal()));
        commentMsg.setComment_status(String.valueOf(CommentStatus.DEFAULT.getVal()));
        commentMsg.setUser_id(user_id);
        commentMsg.setUpvote_num(0);
        commentService.save(commentMsg);

        //更新被回复的评论的时间
        reply_comment.setUpdate_time(System.currentTimeMillis());
        reply_comment.setReply_time(System.currentTimeMillis());
        commentService.update(reply_comment);
        CommentSaveBack commentSaveBack = new CommentSaveBack();
        return VOUtil.setSuccessResult(commentSaveBack);
    }

    public CommentSaveBack funcUpdateComment(CommentUpdateForm commentUpdateForm) {
        String comment_id = commentUpdateForm.getComment_id();
        String comment_content = commentUpdateForm.getComment_content();
        if(StringReplacer.hasSensitiveWord(comment_content,commentUpdateForm.getCompany_id())){
            return VOUtil.genErrorResult(COMMENT_BLACK_WORD_EXIT,CommentSaveBack.class);
        }
        Long user_id = commentUpdateForm.getUser().getUser_id();
        if(blackuserService.isUserExit(new BlackUser(null,user_id,""))){
            return VOUtil.genErrorResult(USER_IN_BLACK_LIST,CommentSaveBack.class);
        }
        CommentMsg commentMsg = commentService.get(comment_id);
        if (commentMsg == null) {
            return VOUtil.genErrorResult(HSBCPSErrorCodes.CommentErrorInfo.COMMENT_NOT_EXIST,
                    CommentSaveBack.class);
        }else if(!commentMsg.getUser_id().equals(commentUpdateForm.getUser().getUser_id())) {
            //非自己评论不能修改
            return VOUtil.genErrorResult(HSBCPSErrorCodes.CommentErrorInfo.COMMENT_NOT_YOURS,
                    CommentSaveBack.class);
        }
        commentMsg.setComment_content(comment_content);
        commentService.update(commentMsg);
        CommentSaveBack commentSaveBack = new CommentSaveBack();
        return VOUtil.setSuccessResult(commentSaveBack);
    }

    public CommentSaveBack funcCloseComment(CommentStatusForm commentStatusForm) {
        if(commentStatusForm.getUser().getUser_type().equals(UserType.LEADER.getVal())){
            return VOUtil.genErrorResult(HSBCPSErrorCodes.CommentErrorInfo.NOT_ALLOW_TO_CHANGE,
                    CommentSaveBack.class);
        }
        String comment_id = commentStatusForm.getComment_id();
        CommentMsg commentMsg = commentService.get(comment_id);
        if (commentMsg == null ){
            return VOUtil.genErrorResult(HSBCPSErrorCodes.CommentErrorInfo.COMMENT_NOT_EXIST,
                    CommentSaveBack.class);
        }
        commentMsg.setClose_status(String.valueOf(CloseStatus.CLOSE.getVal()));
        commentService.update(commentMsg);
        CommentSaveBack commentSaveBack = new CommentSaveBack();
        return VOUtil.setSuccessResult(commentSaveBack);
    }

    @Transactional
    public CommentSaveBack fucTopComment(CommentTopForm commentTopForm) {
        if(commentTopForm.getUser().getUser_type().equals(UserType.LEADER.getVal())){
            return VOUtil.genErrorResult(HSBCPSErrorCodes.CommentErrorInfo.NOT_ALLOW_TO_CHANGE,
                    CommentSaveBack.class);
        }
        String comment_id = commentTopForm.getComment_id();
        CommentMsg commentMsg = commentService.get(comment_id);
        if (commentMsg == null ){
            return VOUtil.genErrorResult(HSBCPSErrorCodes.CommentErrorInfo.COMMENT_NOT_EXIST,
                    CommentSaveBack.class);
        }
        if (commentMsg.getComment_target_id()==null){
            return VOUtil.genErrorResult(HSBCPSErrorCodes.CommentErrorInfo.NOT_ALLOW_TOP_REPLY,
                    CommentSaveBack.class);
        }
        CombinationEntity combination = combineService.get(commentMsg.getComment_target_id().toString());
        if (!commentTopForm.getUser().getUser_id().equals(combination.getUser_id())){
            return VOUtil.genErrorResult(HSBCPSErrorCodes.CommentErrorInfo.NOT_ALLOW_TO_CHANGE,
                    CommentSaveBack.class);
        }
        //取消其他置顶（只允许一个置顶）
        commentService.cancelTopByTargetId(commentMsg);
        commentMsg.setIs_top(TopStatus.IS_TOP.getVal());
        commentService.update(commentMsg);
        CommentSaveBack commentSaveBack = new CommentSaveBack();
        return VOUtil.setSuccessResult(commentSaveBack);
    }

    public CommentQueryResult queryCommentsByTarget(CommentTargetForm targetForm){
        //组合评论需要用combi_code装换成comment_id
        String comment_type = targetForm.getComment_type();
        Long user_id = targetForm.getUser()==null?null:targetForm.getUser().getUser_id();
        CombinationEntity combinationEntity = new CombinationEntity();
        if (comment_type.equals(CommentType.COMBINATION.getVal())){
            combinationEntity = combineService.getCombinationByCode(targetForm.getComment_target_id());
            if (combinationEntity == null) {
                return VOUtil.genErrorResult(HSBCPSErrorCodes.CombinationErrorInfo.COMBINATION_NOT_EXIST,
                        CommentQueryResult.class);
            }
            //如果请求主要评论则返回投顾在该观点发表的评论
            if (targetForm.getMain_flag()!=null && targetForm.getMain_flag().equals("1")){
                targetForm.setUser_id(combinationEntity.getUser_id());
            }
            targetForm.setComment_target_id(String.valueOf(combinationEntity.getCombination_id()));
        } else {
            return VOUtil.genErrorResult(HSBCPSErrorCodes.CommentErrorInfo.NOT_AVAILIABLE_TYPE,
                    CommentQueryResult.class);
        }
        List<CommentUser> commentUsers = commentService.queryCommentsByTarget(targetForm);
        List<Long> commentIds = new ArrayList<>();
        for(CommentUser commentUser : commentUsers){
            commentIds.add(commentUser.getComment_id());
        }
        //有评论情况下去查询回复
        if (commentIds !=null && commentIds.size()>0) {
            List<CommentUser> replyComments = commentService.queryCommentsByIds(commentIds);
            commentUsers.addAll(replyComments);
        }
        List<CommentVO> commentVOs = JSON.parseArray( JSON.toJSONString(commentUsers),CommentVO.class);
        //添加是否为主要评论
        for (CommentVO commentVo: commentVOs) {
            if (commentVo.getUser_id()==combinationEntity.getUser_id().longValue()){
                commentVo.setMain_flag(1);
            } else {
                commentVo.setMain_flag(0);
            }
        }
        //添加点赞标志
        setUpvoteInfo(commentVOs,user_id);
        //获取用户中心的昵称头像
        List<Long> user_id_list = new ArrayList<>();
        for (CommentVO commentVO : commentVOs) {
            user_id_list.add(commentVO.getUser_id());
        }
        String user_ids = StringUtils.join(user_id_list,",");
        Map<Long,UserEntityVO> userMap = new HashMap();
        UsersQueryVo usersQueryVo = userCenterService.func_users_query(user_ids);
        if (VOUtil.isSuccess(usersQueryVo)){
            for (UserEntityVO user : usersQueryVo.getData_list()){
                user.setAlias_name(StringUtil.replaceMobile(user.getAlias_name()));//修改单号M201701170424
                userMap.put(user.getUser_id(),user);
            }
        }
        for (CommentVO commentVO : commentVOs) {
            if (userMap.get(commentVO.getUser_id())!= null) {
                commentVO.setAlias_name(userMap.get(commentVO.getUser_id()).getAlias_name());
                commentVO.setAvatar(userMap.get(commentVO.getUser_id()).getAvatar());
            }
        }
        CommentQueryResult result = new CommentQueryResult();
        result.setData_list(commentVOs);
        result.setTotal_item_num(commentService.countByTargetId(targetForm));
        return VOUtil.setSuccessResult(result);
    }

    public CommentSearchResult funcSearchComment(CommentSearchForm commentSearchForm) {
        //组合评论需要用combi_code装换成comment_id
        String comment_type = commentSearchForm.getComment_type();
        if (comment_type.equals(CommentType.COMBINATION.getVal())){
            CombinationEntity combinationEntity =
                    combineService.getCombinationByCode(commentSearchForm.getComment_target_id());
            if (combinationEntity == null) {
                return VOUtil.genErrorResult(HSBCPSErrorCodes.CombinationErrorInfo.COMBINATION_NOT_EXIST,
                        CommentSearchResult.class);
            }
            commentSearchForm.setComment_target_id(String.valueOf(combinationEntity.getCombination_id()));
        } else {
            return VOUtil.genErrorResult(HSBCPSErrorCodes.CommentErrorInfo.NOT_AVAILIABLE_TYPE,
                    CommentSearchResult.class);
        }
        //评论搜索
        List<CommentUser> commentUsers = commentService.searchComments(commentSearchForm);
        List<Long> commentIds = new ArrayList<>();
        for(CommentUser commentUser : commentUsers){
            commentIds.add(commentUser.getComment_id());
        }
        //有评论情况下去查询回复
        if(commentIds!=null && commentIds.size()>0) {
            List<CommentUser> replyComments = commentService.queryCommentsByIds(commentIds);
            commentUsers.addAll(replyComments);
        }
        //添加是否能被投顾端修改
        List<CommentSearchResultData> commentSearchResultDatas =
                JSON.parseArray(JSON.toJSONString(commentUsers), CommentSearchResultData.class);
        for (CommentSearchResultData commentSearchResultData :commentSearchResultDatas) {
            if(commentSearchForm.getUser().getUser_id().equals(commentSearchResultData.getUser_id())){
                commentSearchResultData.setMod_status(AllowModifyStatus.ALLOW_MODIFY.getVal());
            }else {
                commentSearchResultData.setMod_status(AllowModifyStatus.NOT_ALLOW_MODIFY.getVal());

            }
        }
        //头像昵称从用户中心获取
        List<Long> user_id_list = new ArrayList<>();
        for (CommentSearchResultData commentSearchResultData : commentSearchResultDatas) {
            user_id_list.add(commentSearchResultData.getUser_id());
        }
        String user_ids = StringUtils.join(user_id_list,",");
        Map<Long,UserEntityVO> userMap = new HashMap();
        UsersQueryVo usersQueryVo = userCenterService.func_users_query(user_ids);
        if (VOUtil.isSuccess(usersQueryVo)){
            for (UserEntityVO user : usersQueryVo.getData_list()){
                user.setAlias_name(StringUtil.replaceMobile(user.getAlias_name()));//修改单号M201701170424
                userMap.put(user.getUser_id(),user);
            }
        }
        for (CommentSearchResultData commentSearchResultData : commentSearchResultDatas) {
            if (userMap.get(commentSearchResultData.getUser_id())!=null) {
                commentSearchResultData.setAlias_name(userMap.get(commentSearchResultData.getUser_id()).getAlias_name());
                commentSearchResultData.setAvatar(userMap.get(commentSearchResultData.getUser_id()).getAvatar());
            }
        }
        CommentSearchResult result = new CommentSearchResult();
        result.setData_list(commentSearchResultDatas);
        return VOUtil.setSuccessResult(result);
    }

    @Transactional
    public CommentUpvoteResult funcUpvoteComment(CommentUpvoteForm form) {
        Long user_id = form.getUser().getUser_id();
        Long comment_id = Long.valueOf(form.getComment_id());
        String upvote_type = String.valueOf(UpvoteType.COMMENT_UPVOTE.getVal());
        String upvote_flag = form.getUpvote_flag();
        CommentMsg commentMsg = commentService.get(form.getComment_id());
        if (commentMsg == null) {
            return VOUtil.genErrorResult(HSBCPSErrorCodes.CommentErrorInfo.COMMENT_NOT_EXIST,
                    CommentUpvoteResult.class);
        }
        if (upvote_flag.equals(UpvoteFlag.UPVOTE.getVal())){
            //点赞
            if (UpvoteCacheUtil.isUpvoteComment(comment_id,user_id)) {//已点赞
                return VOUtil.genErrorResult(HSBCPSErrorCodes.CommentErrorInfo.COMMENT_ALREADY_UPVOTE,
                        CommentUpvoteResult.class);
            }
            UpvoteCacheUtil.addCommentUpvoteRecord(comment_id,user_id);
            UpvoteRecord upvoteRecord = new UpvoteRecord();
            upvoteRecord.setCompany_id(form.getCompany_id());
            upvoteRecord.setUser_id(user_id);
            upvoteRecord.setUpvote_target_id(comment_id);
            upvoteRecord.setUpvote_type(String.valueOf(UpvoteType.COMMENT_UPVOTE.getVal()));
            upvoteRecord.setCreate_date(System.currentTimeMillis());
            upvoteRecordService.save(upvoteRecord);
            CommentMsg commentMsg1 = new CommentMsg();
            commentMsg1.setComment_id(comment_id);
            commentMsg1.setUpvote_num(commentMsg.getUpvote_num()+1);
            commentMsg1.setCompany_id(commentMsg.getCompany_id());
            commentService.update(commentMsg1);
        }else if (upvote_flag.equals(UpvoteFlag.CANCEL_UPVOTE.getVal())){
            //取消点赞
            if (!UpvoteCacheUtil.isUpvoteComment(comment_id,user_id)) {//已点赞
                return VOUtil.genErrorResult(HSBCPSErrorCodes.CommentErrorInfo.COMMENT_HAVE_NOT_UPVOTE,
                        CommentUpvoteResult.class);
            }
            UpvoteCacheUtil.delCommentUpvoteRecord(comment_id,user_id);
            UpvoteRecord upvoteRecord = new UpvoteRecord();
            upvoteRecord.setCompany_id(form.getCompany_id());
            upvoteRecord.setUser_id(user_id);
            upvoteRecord.setUpvote_target_id(comment_id);
            upvoteRecord.setUpvote_type(String.valueOf(UpvoteType.COMMENT_UPVOTE.getVal()));
            upvoteRecordService.cancelUpvote(upvoteRecord);
            CommentMsg commentMsg1 = new CommentMsg();
            commentMsg1.setComment_id(comment_id);
            commentMsg1.setUpvote_num(commentMsg.getUpvote_num()-1);
            commentMsg1.setCompany_id(commentMsg.getCompany_id());
            commentService.update(commentMsg1);
        }else {
            return VOUtil.genErrorResult(HSBCPSErrorCodes.CommentErrorInfo.UPVOTE_FLAG_ERROR,
                    CommentUpvoteResult.class);
        }
        CommentUpvoteResult commentUpvoteResult = new CommentUpvoteResult();
        return VOUtil.setSuccessResult(commentUpvoteResult);
    }

    private void setUpvoteInfo(List<CommentVO> commentVOs,Long user_id){
        //游客默认全未点赞
        if (user_id!=null) {
            for (CommentVO commentVO : commentVOs) {
                boolean isUpvote = UpvoteCacheUtil.isUpvoteComment(commentVO.getComment_id(),
                        user_id);
                commentVO.setUpvote_flag(
                        isUpvote ? UpvoteStatus.ALREADY_UPVOTE.getVal() : UpvoteStatus.NOT_UPVOTE.getVal());
            }
        }else {
            for (CommentVO commentVO : commentVOs) {
                commentVO.setUpvote_flag(UpvoteStatus.NOT_UPVOTE.getVal());
            }
        }
    }
}
